﻿using HartConfigTool.HARTCommands.CMDs;
using HartConfigTool.SerialPortUtil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static HartConfigTool.HARTCommands.CMDs.CMD1ReadPV;

namespace HartConfigTool.UI.DebugWindow
{
    internal sealed class CMDsDebugWinHARTCMD0 : CMD0ReadUniqueIdentifier
    {
        public new bool IsCompleted { get; private set; }
        public CMDsDebugWinHARTCMD0(SerialPortsManager serialPortManager) : base(serialPortManager) { }
        protected override async Task SendCMDCode()
        {
            byte[] tempAry = new byte[16];
            byte[] cmdCodeBytes = StructToBytes<HARTCMD0ReadUniqueIdentifierStruct>(HARTCMD0ReadUniqueIdentifierCode);

            Array.Copy(cmdCodeBytes, 5, tempAry, 0, 4);
            cmdCodeBytes[cmdCodeBytes.Length - 1] = HARTProtocolV7.GetCRC(tempAry, (byte)4);

            serialPortManager.DebugMessage("[" + DateTime.Now + "]:-->" + HARTProtocolV7.HexToString(cmdCodeBytes) + "\r\n");

            await serialPortManager.SendCMD(cmdCodeBytes);
        }
        public override async Task ParseResponse(byte[] responseData)
        {
            await Task.Run(() =>
            {
                List<string> parts = new List<string>();
                byte[] bytes = null;
                byte[] data = null;

                data = serialPortManager.GetRxBufferData();

                bytes = HARTProtocolV7.GetDataFrame(data);

                // Debug Message
                serialPortManager.DebugMessage("[" + DateTime.Now + "]:<--" + HARTProtocolV7.HexToString(data) + "\r\n");

                // Information
                parts.Add(bytes[6].ToString()); // byte0
                parts.Add("0x" + (((ushort)bytes[7] << 8) + bytes[8]).ToString("X4")); // byte1-2
                parts.Add(bytes[9].ToString()); // byte3
                parts.Add(bytes[10].ToString()); // byte4
                parts.Add(bytes[11].ToString()); // byte5
                parts.Add(bytes[12].ToString()); // byte6
                parts.Add("0x" + (bytes[13] & 0xf8).ToString("X2")); // byte7, bit3~7
                parts.Add("0x" + (bytes[13] & 0x07).ToString("X2")); // byte7, bit0~2
                parts.Add("0x" + bytes[14].ToString("X2")); // byte8
                parts.Add("0x" + (((uint)bytes[15] << 16) + (((uint)bytes[16] << 8) + bytes[17])).ToString("X6")); // byte9~11
                parts.Add(bytes[18].ToString()); // byte12
                parts.Add(bytes[19].ToString()); // byte13
                parts.Add("0x" + (((ushort)bytes[20] << 8) + bytes[21]).ToString("X4")); // byte14~15
                parts.Add(bytes[22].ToString()); // byte16
                parts.Add("0x" + (((ushort)bytes[23] << 8) + bytes[24]).ToString("X4")); // byte17~18
                parts.Add("0x" + (((ushort)bytes[25] << 8) + bytes[26]).ToString("X4")); // byte19~20
                parts.Add(bytes[27].ToString()); // byte21

                NotifyObservers(CMD0Observers, ObserversInfo.HARTCMD0Observers["All"], parts);

                // HART Rev
                parts.Clear();
                parts.Add(bytes[10].ToString());
                NotifyObservers(CMD0Observers, ObserversInfo.HARTCMD0Observers["HART Rev"], parts);
                // Device ID
                parts.Clear();
                parts.Add((((uint)bytes[15] << 16) + (((uint)bytes[16] << 8) + bytes[17])).ToString("X6"));
                NotifyObservers(CMD0Observers, ObserversInfo.HARTCMD0Observers["Device ID"], parts);
                // Manufacturer ID
                parts.Clear();
                parts.Add((((ushort)bytes[23] << 8) + bytes[24]).ToString("X4"));
                NotifyObservers(CMD0Observers, ObserversInfo.HARTCMD0Observers["Manufacturer ID"], parts);

                serialPortManager.deviceID = ((uint)bytes[15] << 16) + ((uint)bytes[16] << 8) + bytes[17];

                this.serialPortManager.RxDataClear();
            });
        }
    }
}
